#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <unistd.h>    // Unix标准函数接口
#include <pthread.h>    // POSIX线程库

using namespace std;

#define NUM 4  // 定义线程数量

// 线程数据类，用于存储每个线程的信息
class threadData {
public:
    threadData(int number) {
        threadname = "thread-" + to_string(number);  // 构造线程名称
    }

public:
    string threadname;  // 线程名称
};

// 共享资源：票数
int tickets = 1000;  // 模拟1000张票

// 线程执行函数：抢票逻辑
void* getTicket(void* args) {
    // 将void指针转换为threadData指针
    threadData* td = static_cast<threadData*>(args);
    const char* name = td->threadname.c_str();
    
    while (true) {
        if(tickets > 0) {  // 还有票
            usleep(1000);  // 模拟处理延迟
            // 打印抢票信息（存在数据竞争）
            printf("who=%s, get a ticket: %d\n", name, tickets);
            tickets--;     // 票数减一（存在数据竞争）
        }
        else
            break;  // 无票退出
    }
    printf("%s ... quit\n", name);
    return nullptr;
}

// 主函数
int main() {
    vector<pthread_t> tids;           // 存储线程ID
    vector<threadData*> thread_datas; // 存储线程数据
    
    // 创建多个线程
    for (int i = 1; i <= NUM; i++) {
        pthread_t tid;
        threadData* td = new threadData(i);
        thread_datas.push_back(td);
        pthread_create(&tid, nullptr, getTicket, thread_datas[i-1]);
        tids.push_back(tid);
    }

    // 等待所有线程结束
    for (auto thread : tids) {
        pthread_join(thread, nullptr);
    }

    // 清理线程数据
    for (auto td : thread_datas) {
        delete td;
    }
    return 0;
}

// 以下是被注释的代码部分解析：

// #define NUM 3  // 定义3个线程

// // int *p = NULL;  // 用于演示线程本地存储的指针

// // 线程本地存储变量声明
// // __thread int g_val = 100;
// __thread unsigned int number = 0;
// __thread int pid = 0;

// // 线程数据结构
// struct threadData {
//     string threadname;
// };

// // __thread threadData td;  // 线程本地存储的线程数据

// // 将线程ID转换为16进制字符串
// string toHex(pthread_t tid) {
//     char buffer[128];
//     snprintf(buffer, sizeof(buffer), "0x%x", tid);
//     return buffer;
// }

// // 初始化线程数据
// void InitThreadData(threadData *td, int number) {
//     td->threadname = "thread-" + to_string(number);
// }

// // 线程执行函数
// void *threadRoutine(void *args) {
//     // 设置线程为分离状态
//     pthread_detach(pthread_self());

//     // int test_i = 0;
//     threadData *td = static_cast<threadData *>(args);
//     // if(td->threadname == "thread-2") p = &test_i;
    
//     // 获取线程标识和进程ID
//     string tid = toHex(pthread_self());
//     int pid = getpid();

//     // 循环打印线程信息
//     int i = 0;
//     while (i < 10) {
//         cout << "tid: " << tid << ", pid: " << pid << endl;
//         sleep(1);
//         i++;
//     }

//     delete td;
//     return nullptr;
// }

// int main() {
//     // 存储线程ID的vector
//     vector<pthread_t> tids;
    
//     // 创建多个线程
//     for (int i = 0; i < NUM; i++) {
//         pthread_t tid;
//         threadData *td = new threadData;
//         InitThreadData(td, i);
//         pthread_create(&tid, nullptr, threadRoutine, td);
//         tids.push_back(tid);
//     }
//     sleep(1);

//     // 等待所有线程结束
//     for (int i = 0; i < tids.size(); i++) {
//         int n = pthread_join(tids[i], nullptr);
//         printf("n = %d, who = 0x%x, why: %s\n", 
//                n, tids[i], strerror(n));
//     }

//     return 0;
// }